/*
 * Copyright 2013 Kenneth Syharath
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the license at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the license is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the license for specific language governing
 * permissions and limitations under the license.
 */

package shuffler_classes;

import java.util.List;

/**
 * ShuffleDispatch.java
 * @author Kenneth
 * @version 1.1
 * All functions form a simple, intuitive way to interface with the 
 * Shuffles.java library.
 * 
 * Changelog
 * - July 18th, 2013 (From 1.0 to 1.1)
 * * Added linked versions of the functions; allowing users to rapidly
 * * link various shuffles together rather than having to call the dispatch
 * * function several times explicitly.
 */
public class ShuffleDispatch {
	private static enum ShuffleType {
		FISHERYATES,
		PILE,
		RIFFLE,
		STRIP,
		MONGEAN
	}
	
	private static ShuffleType findShuffleType(String theShuffle) {
		if (theShuffle.equalsIgnoreCase("FISHERYATES"))
			return ShuffleType.FISHERYATES;
		if (theShuffle.equalsIgnoreCase("PILE"))
			return ShuffleType.PILE;
		if (theShuffle.equalsIgnoreCase("RIFFLE"))
			return ShuffleType.RIFFLE;
		if (theShuffle.equalsIgnoreCase("STRIP"))
			return ShuffleType.STRIP;
		if (theShuffle.equalsIgnoreCase("MONGEAN"))
			return ShuffleType.MONGEAN;
		return null;
	}
	
	public static List standardDispatch(String theShuffle, List theArray) {
		if (theArray == null || theArray.isEmpty())
			throw new IllegalArgumentException("Invalid Array");
		ShuffleType theType = findShuffleType(theShuffle);
		
		switch (theType) {
		case FISHERYATES:
			return Shufflers.fisherYatesShuffle(theArray); 
		case PILE:
			return Shufflers.pileShuffle(theArray, 5, 0, false);
		case RIFFLE:
			return Shufflers.riffleShuffle(theArray, 2, true);
		case STRIP:
			return Shufflers.stripShuffle(theArray, 0.25, 0.25, 0);
		case MONGEAN:
			return Shufflers.mongeanShuffle(theArray);
		default:
			throw new IllegalArgumentException("Invalid Shuffle Type");
		}
	}
	
	public static List standardLinkedDispatch(String[] theShuffles, List theArray) {
		List result = theArray;
		for (int i = 0; i< theShuffles.length; i++)
			result = standardDispatch(theShuffles[i], theArray);
		return result;
	}
	
	public static List customArgDispatch(String theShuffle, List theArray,
			Object[] args) {
		if (theArray == null || theArray.isEmpty())
			throw new IllegalArgumentException("Invalid Array");
		ShuffleType theType = findShuffleType(theShuffle);
		try {
			switch (theType) {
			case FISHERYATES:
				return Shufflers.fisherYatesShuffle(theArray);
			case PILE:
				return Shufflers.pileShuffle(theArray, (Integer) args[0], 
						(Integer) args[1], (Boolean) args[2]);
			case RIFFLE:
				return Shufflers.riffleShuffle(theArray, (Integer) args[0],
						(Boolean) args[1]);
			case STRIP:
				return Shufflers.stripShuffle(theArray, (Double) args[0],
						(Double) args[1], (Integer) args[2]);
			case MONGEAN:
				return Shufflers.mongeanShuffle(theArray);
			default:
				throw new IllegalArgumentException("Invalid Shuffle Type");
			}
		}
		catch (ClassCastException e) {
			throw new IllegalArgumentException("Invalid Arguments for " + theType);
		}
	}
	
	public static List linkedCustomArgDispatch (String[] theShuffles, List theArray,
			Object[][] theArgs) {
		if (theShuffles.length != theArgs.length || theShuffles.length == 0 
				|| theArgs.length == 0)
			throw new IllegalArgumentException("Invalid Shuffle/Arg Arguments");
		List result = theArray;
		for (int i = 0; i < theShuffles.length; i++) {
			result = customArgDispatch(theShuffles[i], result, theArgs[i]);
		}
		return result;
	}
}
